package im.oen.boot.common.utils;

import im.oen.boot.common.data.ImageFontData;
import im.oen.boot.common.data.Point;
import im.oen.boot.common.data.Rectangle;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;

/**
 * <p>描述：https://www.jianshu.com/p/13d94f2a8f64</p>
 *
 * <p>创建时间：2021-12-15 18:16</p>
 * <p>更新时间：暂无</p>
 *
 * @author Kevin.Xu
 * @version 1.0
 */
public class ImageUtil {

    private static final Color[] colors = new Color[]{Color.RED, Color.BLACK, Color.BLUE, Color.ORANGE, Color.YELLOW,
            Color.LIGHT_GRAY, Color.GRAY, Color.PINK, Color.GREEN, Color.MAGENTA, Color.CYAN};

    public static BufferedImage read(String path) {
        return ImageUtil.read(new File(path));
    }

    public static BufferedImage read(final File file) {
        if (file == null || !file.exists()) {
            return null;
        }
        return Runner.safeRun(() -> ImageIO.read(file));
    }

    public static BufferedImage resize(int w, int h, BufferedImage image) {
        if (image == null) {
            return null;
        }

        if (image.getWidth() == w && image.getHeight() == h) {
            return image;
        }
        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        img.getGraphics().drawImage(image.getScaledInstance(w, h, Image.SCALE_SMOOTH), 0, 0, null);
        return img;
    }

    public static BufferedImage writeFont(BufferedImage image, List<ImageFontData> fonts) {
        Graphics2D g = image.createGraphics();
        for (ImageFontData data : fonts) {
            g.setColor(data.getColor());
            g.setFont(new Font(data.getFontName(), data.isBold() ? Font.BOLD : Font.PLAIN, data.getSize()));
            g.drawString(data.getContent(), data.getX(), data.getY());
        }
        g.dispose();
        return image;
    }

    public static BufferedImage cover(BufferedImage image, BufferedImage cover, int x, int y) {
        Graphics2D g = image.createGraphics();
        g.drawImage(cover, x, y, cover.getWidth(), cover.getHeight(), null);
        g.dispose();
        return image;
    }

    public static BufferedImage merge(BufferedImage image1, BufferedImage image2, boolean horizontal) {
        int w1 = image1.getWidth(), w2 = image2.getWidth(), h1 = image1.getHeight(), h2 = image2.getHeight();
        int w = horizontal ? w1 + w2 : (w1 > w2 ? w1 : w2);
        int h = horizontal ? (h1 > h2 ? h1 : h2) : h1 + h2;

        int[] imgArray1 = new int[w1 * h1];
        int[] img1 = image1.getRGB(0, 0, w1, h1, imgArray1, 0, w1);

        int[] imgArray2 = new int[w2 * h2];
        int[] img2 = image2.getRGB(0, 0, w2, h2, imgArray2, 0, w2);

        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        image.setRGB(0, 0, w1, h1, imgArray1, 0, w1);
        if (horizontal) {
            image.setRGB(w1, 0, w2, h2, imgArray2, 0, w2);
        } else {
            image.setRGB(0, h1, w2, h2, imgArray2, 0, w2);
        }
        return image;
    }

    public static BufferedImage drawRect(BufferedImage image, Rectangle rect, Color color) {
        if (Checker.hasEmpty(image, rect, color)) {
            return image;
        }
        Graphics g = image.getGraphics();
        g.setColor(color);
        rect.drawRect(g);
        g.dispose();
        return image;
    }

    public static BufferedImage drawLine(BufferedImage image, Rectangle rect, Color color) {
        if (Checker.hasEmpty(image, rect, color)) {
            return image;
        }
        Graphics g = image.getGraphics();
        g.setColor(color);
        rect.drawLine(g);
        g.dispose();
        return image;
    }

    public static BufferedImage drawLine(BufferedImage image, Point a, Point b, Color color) {
        if (Checker.hasEmpty(image, a, b, color)) {
            return image;
        }
        Graphics g = image.getGraphics();
        g.setColor(color);
        g.drawLine((int) a.getX(), (int) a.getY(), (int) b.getX(), (int) b.getY());
        g.dispose();
        return image;
    }

    public static BufferedImage drawInterestPoint(BufferedImage image, List<Point> points) {
        if (Checker.hasEmpty(image, points)) {
            return image;
        }
        Graphics g = image.getGraphics();
        for (Point point : points) {
            g.setColor(randomColor());
            g.drawRoundRect((int) point.getX() - 5, (int) point.getY() - 5, 10, 10, 10, 10);
        }
        g.dispose();
        return image;
    }

    public static Color randomColor() {
        int idx = UUID.random(colors.length);
        return colors[idx];
    }
}
